
//@ts-nocheck
import currency from 'currency.js';

export interface IMath {
  add: (...numbers: number[]) => number;
  substract: (...numbers: number[]) => number;
  multiply: (...numbers: number[]) => number;
  divide: (...numbers: number[]) => number;
  precisionTransfer: (value: number, precision: number) => number;
  scope: (precision: number, method: keyof IMath, ...numbers: number[]) => number;
  format: (num: number)=> string
}

export function MathCreator(precision = 2) {
  let globalPrecision = precision;

  const math: IMath = {
    // setPrecision(precision: number) {
    //     globalPrecision = precision;
    // },

    add(...numbers: Array<number>): number {
      return numbers.reduce((previousValue: currency, currentValue: number) => {
        return previousValue.add(currentValue);
      }, currency(0, { precision: globalPrecision })).value;
    },

    /**
     * subtract 减
     * @param numbers
     */
    substract(...numbers: Array<number>): number {
      const minuend = numbers.shift();
      return numbers.reduce((previousValue: currency, currentValue: number) => {
        return previousValue.subtract(currentValue);
      }, currency(minuend, { precision: globalPrecision })).value;
    },

    /**
     * 乘法
     * @param numbers
     */
    multiply(...numbers: Array<number>): number {
      const multiplier = numbers.shift();
      return numbers.reduce((previousValue: currency, currentValue: number) => {
        return previousValue.multiply(currentValue);
      }, currency(multiplier, { precision: globalPrecision })).value;
    },

    /**
     * 除法
     * @param numbers
     */
    divide(...numbers: Array<number>): number {
      const divisor = numbers.shift();
      return numbers.reduce((previousValue: currency, currentValue: number) => {
        return previousValue.divide(currentValue);
      }, currency(divisor, { precision: globalPrecision })).value;
    },

    /**
     * 小数位转换
     */
    precisionTransfer(value: number, precision: number): number {
      return currency(value, { precision: precision }).value;
    },

    scope(precision: number, method: keyof IMath, ...numbers: number[]) {
      const oldPrecision = globalPrecision;
      globalPrecision = precision;
      const result = this[method](...numbers);
      globalPrecision = oldPrecision;
      return result;
    },
    format: (num)=>{
        return currency(num, { symbol: '' }).format()
    }
  };

  return math;
}

export const math = MathCreator();
